package org.czf.zk;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.IZkStateListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.List;

@Slf4j
public class NormalZookeeperTest {

    public static void main(String[] args) throws IOException {
        log.info("main start");
        //建立连接
        //zkServers: Zookeeper服务器IP地址和端口号，如果是集群情况下用逗号分割多个Zookeeper服务器地址
        //sessionTimeout: 会话超时时间
        //connectionTimeout: 连接超时时间
        ZkClient zkClient = new ZkClient("47.115.227.96:2181", 60000, 50000);

        createNode(zkClient);
//        readNodeData(zkClient);
//        writeData(zkClient);
//        testSubscribeStateChanges(zkClient);
    }



    public static void createNode(ZkClient zkClient){
        Person person = new Person();
        person.setName("zhangsan");
        person.setId(10086);


        //创建持久节点
        zkClient.createPersistent("/new_node", person);
        //创建持久顺序节点
        String persistentSequential = zkClient.createPersistentSequential("/ps_node", person);
        log.debug(persistentSequential);
        //创建临时节点
        zkClient.createEphemeral("/e_node", person);
        //创建临时顺序节点
        zkClient.createEphemeralSequential("/ps_node", person);

        //关闭客户端
        //关闭客户端的同时，前面创建的临时节点也会被删除
        zkClient.close();

    }

    public static void readNodeData(ZkClient zkClient) {

        Stat stat = new Stat();
        Person person = zkClient.readData("/p_node", stat);
        log.info("节点状态信息：" + JSON.toJSONString(person));
        log.info("节点数据：" + JSON.toJSONString(stat));

        zkClient.close();
    }

    public static void writeData(ZkClient zkClient) {
        zkClient.writeData("/p_node","write",0);
        zkClient.close();
    }

    public static void testSubscribeChildChanges(ZkClient zkClient) throws IOException {
        log.debug("start");
        zkClient.subscribeChildChanges("/p_node", new IZkChildListener(){

            //子节点改变时调用
            @Override
            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                log.info(parentPath + "子节点发生改变");
                log.info("当前子节点列表：" + currentChilds);
            }

        });

        //阻塞客户端，便于测试
        System.in.read();
        log.debug("next");
        
    }

    public static void testSubscribeDataChanges(ZkClient zkClient) throws IOException {
        log.debug("start");
        zkClient.subscribeDataChanges("/p_node", new IZkDataListener(){

            //节点数据改变时调用
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                
                log.info(dataPath + "节点数据发生变化");
                log.info("修改后的数据为：" + data.toString());
            }

            //节点被删除时调用
            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                log.info(dataPath + "节点已被删除");
            }
        });

        //阻塞客户端，便于测试
        System.in.read();
    }

    public static void testSubscribeStateChanges(ZkClient zkClient) throws IOException {
        log.info("start");
        zkClient.subscribeStateChanges(new IZkStateListener(){

            //当zookeeper连接状态改变时调用
            @Override
            public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
                log.info("当前状态" + state);
            }

            //在zookeeper会话过期并且创建了一个新的会话之后调用
            @Override
            public void handleNewSession() throws Exception {
                log.info("会话过期，已创建新的会话");
            }

            //当会话不能重新建立时调用
            @Override
            public void handleSessionEstablishmentError(Throwable error) throws Exception {
                error.printStackTrace();
            }
        });

        //阻塞客户端，便于测试
        System.in.read();
    }
}
